<template>
	<div class="single_image_upload">
		<el-upload
			ref="upload"
			:limit="1"
			:class="['upload_box', { hide: !!imageUrl }]"
			:action="uploadImgUrl"
			:on-success="handleUploadSuccess"
			:before-upload="handleBeforeUpload"
			:on-error="handleUploadError"
			:show-file-list="false"
			:headers="headers"
			:accept="uploadAccept"
			:data="uploadParams"
		>
			<el-button type="text" class="uploadBtn" icon="el-icon-plus"></el-button>
		</el-upload>
		<div class="upload_tip" v-if="!!uploadTips || $slots.tips">
			<slot name="tips">{{ uploadTips }}</slot>
		</div>
		<div class="upload_img" v-if="!!imageUrl">
			<el-image ref="preview" :src="imageUrl" :preview-src-list="previewImage" fit="contain"></el-image>
			<el-button-group>
				<el-button type="text" title="修改" icon="el-icon-edit" @click="handleAmendUpload()"></el-button>
				<el-button type="text" title="预览" icon="el-icon-search" @click="handlePreviewImage()"></el-button>
				<el-button type="text" title="删除" icon="el-icon-delete" @click="handleDeleteImage()"></el-button>
			</el-button-group>
		</div>
	</div>
</template>

<script>
import { mapActions } from 'vuex';
export default {
	name: 'swImageUploader',
	props: {
		value: String,
		// 文件类型, 例如['png', 'jpg', 'jpeg']
		accept: {
			type: String,
			default: 'png,jpg,jpeg,webp'
		},
		//上传类型
		uploadType: {
			type: String,
			default: '1'
		},
		// 是否显示提示
		uploadTips: {
			type: String,
			default: ''
		}
	},
	data() {
		return {
			uploadImgUrl: `${process.env.VUE_APP_BASEURL}tbSysAttachment/upload`, // 上传的图片服务器地址
			headers: { Authorization: this.$local.get('token') },
			uploadParams: { showType: '1', type: this.uploadType },
			imageUrl: '',
			imageId: ''
		};
	},
	watch: {
		value(val) {
			this.imageId = val;
		},
		imageId: {
			handler(val) {
				this.$emit('input', val);
				if (!val) return false;
				this.getFileUrl(val).then((res) => {
					this.imageUrl = window.staticPath + res;
				});
			},
			immediate: true
		}
	},
	computed: {
		uploadAccept() {
			let suffixArr = this.accept.split(',').map((item) => '.' + item);
			return suffixArr.join();
		},
		previewImage() {
			return [this.imageUrl];
		}
	},
	methods: {
		...mapActions(['getFileUrl']),
		//修改上传
		handleAmendUpload() {
			this.$refs['upload'].$el.querySelector('.uploadBtn').click();
		},

		// 删除图片
		handleDeleteImage() {
			this.imageId = '';
			this.imageUrl = '';
		},

		//预览图片
		handlePreviewImage() {
			this.$refs['preview'].clickHandler();
		},

		// 上传前loading加载
		handleBeforeUpload(file) {},

		// 文件个数超出
		handleExceed() {
			this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
		},

		// 上传成功回调
		handleUploadSuccess(res, file) {
			if (res.code === 0) {
				let datas = !res.data ? {} : res.data[0];
				this.imageId = datas.id;
				this.imageUrl = datas.originalAddr;
			}
		},

		// 上传失败
		handleUploadError() {
			this.$modal.msgError('上传图片失败，请重试');
			this.$modal.closeLoading();
		}
	}
};
</script>

<style lang="scss" scoped>
.single_image_upload::v-deep {
	position: relative;

	.upload_box {
		width: 148px;
		height: 148px;
		border-radius: 4px;
		border: dashed 1px #c0c4cc;

		&.hide {
			opacity: 0;
		}

		.el-button.uploadBtn {
			padding: 0;
			margin: 0;
			font-size: 24px;
		}
	}

	.el-upload {
		position: relative;
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.upload_tip {
		color: #909399;
		font-size: 14px;
		line-height: 24px;
		margin-top: 6px;
	}

	.upload_img {
		position: absolute;
		top: 0;
		left: 0;
		width: 148px;
		height: 148px;
		border-radius: 4px;
		border: solid 1px #c0c4cc;

		.el-image {
			display: block;
			width: 100%;
			height: 100%;
			object-fit: contain;
			background-color: rgba(0, 0, 0, 0.05);
		}

		&:hover {
			.el-button-group {
				display: flex;
			}
		}
	}

	.el-button-group {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: none;
		align-items: center;
		justify-content: space-around;
		background-color: rgba(0, 0, 0, 0.75);

		.el-button {
			margin: 0;
			padding: 5px;
			font-size: 18px;
			color: #fff;
		}
	}
}
</style>
